Skip to content

[mypyc] Fix decorated and overloaded __init__ in native classes - #22169

Merged
p-sawicki merged 1 commit into
python:masterfrom
rheard:fix-mypyc-1246
Oct 19, 2026
Merged

p-sawicki merged 1 commit into
python:masterfrom
rheard:fix-mypyc-1246

Conversation

@rheard

@rheard rheard commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Fixes mypyc/mypyc#1246.
Fixes mypyc/mypyc#1057.
Fixes mypyc/mypyc#961.

prepare_init_method() only set up the constructor of a native class when the __init__ symbol was a FuncDef. With an overloaded __init__, or one with a decorator, the class kept the default constructor without arguments, while the generated code still called the function below the decorators natively:

Changes:

  • prepare_init_method() looks through overloads and decorators. The implementation of an overloaded __init__, or an __init__ whose decorators mypy removed, is a regular native method, and the class gets a native constructor with its signature.
  • A decorated __init__ has no entry in method_decls, like other decorated methods, since only the decorated callable can be called. Its class, and subclasses that inherit it, are now initialized through tp_init, like a class that inherits __init__ from a non-native class: the constructor takes *args, **kwargs, tp_new doesn't call __init__, and the generated tp_init calls the wrapper function, as it does for a class that allows interpreted subclasses. The new ClassIR.get_native_init() is used for this, and by the always-defined attribute analysis, which can't assume that the undecorated function runs.
  • prepare_init_method() now runs after the method declarations of all classes are prepared, because in an import cycle a class can be prepared before the base class that defines its __init__. It uses method_decls and not the decorator list, since mypy doesn't keep decorators in its cache and the base class may be loaded from there in an incremental build.
  • A super().m() or Class.m(self) call isn't bound to a native method if the lookup finds a method that isn't native first. Besides __init__, this fixes a super() call to a decorated method of a trait when a later class in the MRO has a native method with the same name.

Notes:

@p-sawicki p-sawicki left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, just needs a rebase.

@p-sawicki
p-sawicki merged commit 1a84743 into python:master Oct 19, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants